<?php

namespace App\Cost;

class BlockBookingCost extends AbstractCost
{
    /**
     * @var BlockBookingStage[] 包段场次 目前只允许两场
     */
    public $blockBookingStages = [];

    /**
     * @var int 当超时类型为BlockBooking时，超过加收下一场的分钟数
     */
    public int $exceedBlockBookingMinutes = 0;

    /**
     * @var int 当超时类型不为BlockBooking时，每小时的计费价格
     */
    public int $exceedPerHourPrice = 0;

    /**
     * 获取出包场场次 index
     * @param string $startTime
     * @return int
     */
    public function getBlockBookingIndex(string $startTime): int|null
    {
        $h = date('H', strtotime($startTime));

        foreach ($this->blockBookingStages as $k => $bookingStage) {

            if ($h >= $bookingStage->startHour && $h <= $bookingStage->endHour) {

                return $k;
            }
        }
    }

    protected function getCost(string $startTime, string $endTime): Price
    {
        $blockBookingIndex = $this->getBlockBookingIndex($startTime);

        if (is_null($blockBookingIndex))
            throw new \Exception('开始时间不在包场时间范围内');

        $blockBooking = $this->blockBookingStages[$blockBookingIndex];
        //超时分钟数
        $startDay = date('Y-m-d', strtotime($startTime));
        $exceedMinutes = (strtotime($endTime) - strtotime($startDay." ".$blockBooking->endHour.":00:00")) / 60;

        if ($exceedMinutes <= 0)
            return new Price($blockBooking->price);

        $exceedFee = $this->getExceedBlockBookingFee($exceedMinutes, $startTime);
        $exceedMessage = $this->getExceedMessage();

        return new Price($blockBooking->price, $exceedMinutes, $exceedFee, $exceedMessage);
    }

    protected function getExceedBlockBookingFee($exceedMinutes, string $startTime): int|null
    {
        if ($this->exceedType == ExceedType::BlockBooking) {

            if ($exceedMinutes <= $this->exceedBlockBookingMinutes)
                return 0;
            else {

                //加收下一场包场的价格
                $blockBookingIndex = $this->getBlockBookingIndex($startTime);
                $nextIndex = $blockBookingIndex ^ 1;
                $nextBlockBooking = $this->blockBookingStages[$nextIndex];

                return $nextBlockBooking->price;
            }
        }

        return parent::getExceedFee($exceedMinutes);
    }

    protected function getExceedMessage()
    {
        if ($this->exceedType == ExceedType::BlockBooking)
            return $this->exceedBlockBookingMinutes."分钟之内免费,超过30分钟加收下一场包场费用";

        return parent::getExceedMessage();
    }

    protected function getPricePerMinutes(): float
    {
        return $this->exceedPerHourPrice / 60;
    }

    public function getPerMinutesPrice(): float|null
    {
        return null;
    }
}
